package org.itzheng.itplayer.player

import android.Manifest
import android.content.res.Configuration
import android.graphics.SurfaceTexture
import android.os.Bundle
import android.util.Log
import android.view.*
import android.view.GestureDetector.SimpleOnGestureListener
import android.widget.SeekBar
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import org.itzheng.and.activity.ItActivity
import org.itzheng.and.activity.permissions.IPermissionManager
import org.itzheng.database.entity.PlayHistory
import org.itzheng.itplayer.R
import org.itzheng.itplayer.data.DataVideoPlay
import org.itzheng.itplayer.databinding.FragmentVideoPlayBinding
import org.itzheng.utils.ViewModelUtils
import java.io.File
import java.util.*


/**
 * Title:视频播放<br></br>
 * Description: <br></br>
 *基本上是仿微信的播放器，但是没有拖动关闭的功能
 *
 * @email ItZheng@ZoHo.com
 * Created by itzheng on 2020-8-5.
 */
class VideoPlayFragment : Fragment() {
    private lateinit var viewModel: VideoPlayViewModel
    private lateinit var _binding: FragmentVideoPlayBinding

    private val TAG = "VideoPlayFragment"
    var rootView: View? = null
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        if (rootView == null) {
//            _binding = FragmentVideoPlayBinding.inflate(LayoutInflater.from(activity), null, false)
            rootView = LayoutInflater.from(activity).inflate(R.layout.fragment_video_play, null)
            _binding = FragmentVideoPlayBinding.bind(rootView!!)
            initViewModel()
        }
        Log.w(TAG, "onCreateView: ")
        return rootView
    }

    var mPath = ""
    var mTitle = "";
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mPath = getPath(arguments!!)
        mTitle = getTitle(arguments!!)
    }
//    var path = "http://stream4.iqilu.com/ksd/video/2020/08/03/9a14a19751f9368c5f84df2daba7d195.mp4";

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initView()
        Log.w(TAG, "onViewCreated: ")
    }


    private fun initViewModel() {
        viewModel = ViewModelUtils.getViewModel(this, VideoPlayViewModel::class.java)
        viewModel.apply {
            //加载条
            loadingBarVisibility.observe(viewLifecycleOwner, Observer {
                _binding!!.loadingBar.visibility = it
            })
            //控制栏显示或隐藏
            controllerLayoutVisibility.observe(viewLifecycleOwner, Observer {
                _binding.includeLayoutController.layoutController.visibility = it
                _binding.tvTitle.visibility = it

            })
            //分辨率
            videoResolution.observe(viewLifecycleOwner, Observer {
                _binding.surfaceView.post { resetViewSize(it.first, it.second) }
            })
            bufferingPercent.observe(viewLifecycleOwner, Observer {
                _binding.includeLayoutController.sbProgress.secondaryProgress =
                    (it / 100f * totalDuration.value!!).toInt()
            })
            //时间进度
            totalDuration.observe(viewLifecycleOwner, Observer {
                _binding.includeLayoutController.sbProgress.max = it
                _binding.includeLayoutController.tvTotalTime.text = stringForTime(it)
            })
            currentDuration.observe(viewLifecycleOwner, Observer {
                _binding.includeLayoutController.sbProgress.progress = it
                _binding.includeLayoutController.tvCurrentTime.text = stringForTime(it)
            })
            //播放状态
            playStatus.observe(viewLifecycleOwner, Observer {
                Log.w(TAG, "playStatus: ${it}");
                when (it) {
                    VideoPlayViewModel.PlayStatus.pause, VideoPlayViewModel.PlayStatus.completion -> {
                        _binding.ivPlayBig.visibility = View.VISIBLE
                        _binding.includeLayoutController.ivPlayStatus.setImageResource(R.drawable.ic_media_player_play_arrow)
                        //暂停或者完成就将播放进度保存下来
                        GlobalScope.launch(Dispatchers.IO) {
                            val item = PlayHistory()
                            item.fTitle = mTitle;
                            item.fPath = mPath
                            var fSeek = currentDuration.value ?: 0
                            item.fSeek = fSeek
                            DataVideoPlay.savePlayHistory(item)
                        }


                    }
                    VideoPlayViewModel.PlayStatus.notReady -> {
                        _binding.ivPlayBig.visibility = View.GONE
                    }
                    else -> {
                        _binding.ivPlayBig.visibility = View.GONE
                        _binding.includeLayoutController.ivPlayStatus.setImageResource(R.drawable.ic_media_player_pause)
                    }

                }
                if (it == VideoPlayViewModel.PlayStatus.completion) {
                    mOnCompletionListener?.invoke()
                }
                if (it == VideoPlayViewModel.PlayStatus.playing) {
                    //播放，去获取播放记录，接着上一次播放
                    gotoLastPlay()
                }
            })
        }
//        //添加观察，后台时，自动暂停
        lifecycle.addObserver(viewModel.mediaPlayer)
        viewModel.setOrientation(context!!.resources.configuration.orientation)
        if (isLocal(mPath)) {
            viewModel.setMediaPath(mPath)
        } else {
            //获取内存卡权限
            val itActivity = activity as ItActivity
            itActivity.requestPermissions(object :
                IPermissionManager.OnRequestPermissionListener {
                override fun denyPermissions(isAllDeny: Boolean, permissions: Array<out String>?) {
                    //没有内存卡权限，就不缓存
                    viewModel.setMediaPath(mPath)
                }

                override fun grantPermissions(
                    isAllGrant: Boolean,
                    permissions: Array<out String>?
                ) {
//                    var proxy = getProxy(context)
//                    proxy.startServer()
//                    val proxyUrl = proxy.getProxyUrl(path)
//                    viewModel.setMediaPath(proxyUrl)
                    viewModel.setMediaPath(mPath)
                }
            }, Manifest.permission.WRITE_EXTERNAL_STORAGE)

        }

    }

    /**
     * 如果执行过了就不要再执行
     */
    private var isGot = false;
    private fun gotoLastPlay() {
        if (isGot) {
            return
        }
        lifecycleScope.launch(Dispatchers.IO) {
            //获取播放记录
            val item = DataVideoPlay.getPlayHistory(mPath)
            if (item != null) {
                val totalDuration = viewModel.totalDuration.value ?: 0
                val currentDuration = viewModel.currentDuration.value ?: 0
                //如果记录刚好结束，会造成视频无法重新播放的bug,所以 -200ms
                if (item.fSeek in (currentDuration + 1) until (totalDuration - 200)) {
                    viewModel.seekTo(item.fSeek)
                }
            }
        }
    }

    private fun isLocal(path: String): Boolean {
        return File(path).exists()
    }

    private fun initView() {
        _binding.tvTitle.setText(mTitle)
        //设置显示
        _binding.surfaceView.surfaceTextureListener = object : TextureView.SurfaceTextureListener {
            override fun onSurfaceTextureSizeChanged(
                surface: SurfaceTexture?,
                width: Int,
                height: Int
            ) {
                viewModel.setSurface(Surface(surface))
            }

            override fun onSurfaceTextureUpdated(surface: SurfaceTexture?) {
                viewModel.setSurface(Surface(surface))
            }

            override fun onSurfaceTextureDestroyed(surface: SurfaceTexture?): Boolean {
                return true
            }

            override fun onSurfaceTextureAvailable(
                surface: SurfaceTexture?,
                width: Int,
                height: Int
            ) {
                viewModel.setSurface(Surface(surface))
            }
        }
//        点击最外层
        (_binding.frameLayout.parent as View).setOnTouchListener(object : View.OnTouchListener {
            //点击最外层，设置点击双击事件，单击，弹出进度条，双击暂停开始
            val gestureDetector = GestureDetector(context, object : SimpleOnGestureListener() {
                /**
                 * 发生确定的单击时执行
                 * @param e
                 * @return
                 */
                override fun onSingleTapConfirmed(e: MotionEvent?): Boolean {
//                    Log.w(TAG, "单击确认");
                    viewModel.showProgressBar()
                    return true
                }

                /**
                 * 双击发生时的通知
                 * @param e
                 * @return
                 */
                override fun onDoubleTap(e: MotionEvent?): Boolean {
//                    Log.w(TAG, "双击");
//                    双击暂停开始
                    viewModel.togglePlayStatus()
                    return true
                }

                override fun onDown(e: MotionEvent?): Boolean {
                    return true
                }
            })

            override fun onTouch(v: View?, event: MotionEvent?): Boolean {
                return gestureDetector.onTouchEvent(event)
            }
        })

        _binding.includeLayoutController.sbProgress.setOnSeekBarChangeListener(object :
            SeekBar.OnSeekBarChangeListener {
            override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
                if (fromUser) {
                    viewModel.seekTo(progress)
                }
            }

            override fun onStartTrackingTouch(seekBar: SeekBar?) {

            }

            override fun onStopTrackingTouch(seekBar: SeekBar?) {
            }
        })
        _binding.ivPlayBig.setOnClickListener {
            viewModel.togglePlayStatus()
        }
        _binding.includeLayoutController.ivPlayStatus.setOnClickListener {
            viewModel.togglePlayStatus()
        }

    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        //屏幕变化,如果是横屏，3秒后，隐藏进度条
        viewModel.setOrientation(newConfig.orientation)
        viewModel.updateSize()
    }

    /**
     * 设置显示的大小
     * 目标是保持比例，最大限度的显示，但是不能截取，
     * 即一边完全显示，另一边小于或者完全显示
     */
    private fun resetViewSize(videoWidth: Int, videoHeight: Int) {
        Log.w(TAG, "videoWidth:${videoWidth},videoHeight:${videoHeight}")
        if (videoWidth <= 0 || videoHeight <= 0) return

        val parent = _binding.surfaceView.parent as View
        val pp = parent.parent as View
        var screenWidth = 0
        var screenHeight = 0
        Log.w(TAG, "pp.width:${pp.width},pp.height:${pp.height}")
        if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            screenWidth = Math.max(pp.width, pp.height)
            screenHeight = Math.min(pp.width, pp.height)
        } else {
            screenWidth = Math.min(pp.width, pp.height)
            screenHeight = Math.max(pp.width, pp.height)
        }
        val wf: Float = videoWidth * 1.0f / screenWidth
        val hf: Float = videoHeight * 1.0f / screenHeight
        val layoutParams = parent.layoutParams
        if (wf > hf) {
            layoutParams.width = screenWidth
            layoutParams.height = (screenWidth * 1.0f / videoWidth * videoHeight).toInt()
        } else {
            layoutParams.width = (screenHeight * 1.0f / videoHeight * videoWidth).toInt()
            layoutParams.height = screenHeight
        }
        Log.w(
            TAG,
            "layoutParams.width:${layoutParams.width},layoutParams.height:${layoutParams.height}"
        )
    }

    /**
     * 结束的监听
     */
    private var mOnCompletionListener: (() -> Unit)? = null;
    fun setOnCompletionListener(function: () -> Unit) {
        mOnCompletionListener = function
    }

    companion object {
        private const val STRING_PATH = "STRING_PATH"
        private const val STRING_TITLE = "STRING_TITLE"
        fun newInstance(path: String): VideoPlayFragment {
            return newInstance(path, "")
        }

        fun newInstance(path: String, title: String): VideoPlayFragment {
            val args = Bundle()
            args.putString(STRING_PATH, path)
            args.putString(STRING_TITLE, title)
            val fragment = VideoPlayFragment()
            fragment.arguments = args
            return fragment
        }

        fun getPath(arguments: Bundle): String {
            return arguments.getString(STRING_PATH, "")
        }

        fun getTitle(arguments: Bundle): String {
            return arguments.getString(STRING_TITLE, "")
        }

        //将长度转换为时间
        var mFormatBuilder = StringBuilder()
        var mFormatter: Formatter = Formatter(mFormatBuilder, Locale.getDefault())

        //将长度转换为时间
        fun stringForTime(timeMs: Int): String? {
            val totalSeconds = timeMs / 1000
            val seconds = totalSeconds % 60
            val minutes = totalSeconds / 60 % 60
            val hours = totalSeconds / 3600
            mFormatBuilder.setLength(0)
            return if (hours > 0) {
                mFormatter.format("%d:%02d:%02d", hours, minutes, seconds).toString()
            } else {
                mFormatter.format("%02d:%02d", minutes, seconds).toString()
            }
        }
    }
}